/*
 * Copyright (c) 2015 Isode Limited.
 * All rights reserved.
 * See the COPYING file for more information.
 */

#include <cppunit/extensions/HelperMacros.h>

#include <Swiften/SASL/WindowsServicePrincipalName.h>

using namespace Swift;

class WindowsServicePrincipalNameTest : public CppUnit::TestFixture {
		CPPUNIT_TEST_SUITE(WindowsServicePrincipalNameTest);
		CPPUNIT_TEST(testServiceClass);
		CPPUNIT_TEST(testServiceName);
		CPPUNIT_TEST(testInstanceName);
		CPPUNIT_TEST(testInstancePort);
		CPPUNIT_TEST(testReferrer);
		CPPUNIT_TEST_SUITE_END();

	public:
		void testServiceClass() {
			WindowsServicePrincipalName spn("mlink.adlon.isode.net");

			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/mlink.adlon.isode.net"));

			spn.setServiceClass("ldap");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("ldap/mlink.adlon.isode.net"));

			spn.setServiceClass("中文");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("中文/mlink.adlon.isode.net"));

			try {
				spn.setServiceClass("");
				spn.toString();
				CPPUNIT_ASSERT(false);
			} catch (std::runtime_error) {
				/* expected */
			}

			try {
				spn.setServiceClass("xm/pp"); /* Foward slash not allowed */
				spn.toString();
				CPPUNIT_ASSERT(false);
			} catch (std::runtime_error) {
				/* expected */
			}
		}

		void testServiceName() {
			try {
				WindowsServicePrincipalName spn("");
				spn.toString();
				CPPUNIT_ASSERT(false);
			} catch (std::runtime_error) {
				/* expected */
			}

			try {
				WindowsServicePrincipalName spn2("mlink/adlon.isode.net"); /* Foward slash not allowed */
				spn2.toString();
				CPPUNIT_ASSERT(false);
			} catch (std::runtime_error) {
				/* expected */
			}

			WindowsServicePrincipalName spn3("mlinkÄ.adlon.isode.net");
			CPPUNIT_ASSERT_EQUAL(spn3.toString(), std::string("xmpp/mlinkÄ.adlon.isode.net"));
		}

		void testInstanceName() {
			WindowsServicePrincipalName spn("adlon.isode.net");

			spn.setInstanceName("mlink.adlon.isode.net");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/mlink.adlon.isode.net/adlon.isode.net"));

			spn.setInstanceName("127.0.0.1");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/127.0.0.1/adlon.isode.net"));

			spn.setInstanceName("");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/adlon.isode.net"));

			spn.setInstanceName("cañón.adlon.isode.net");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/cañón.adlon.isode.net/adlon.isode.net"));

			try {
				spn.setInstanceName("mlink/adlon.isode.net"); /* Foward slash not allowed */
				spn.toString();
				CPPUNIT_ASSERT(false);
			} catch (std::runtime_error) {
				/* expected */
			}
		}

		void testInstancePort() {
			WindowsServicePrincipalName spn("adlon.isode.net");

			spn.setInstanceName("mlink.adlon.isode.net");
			spn.setInstancePort(6222);
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/mlink.adlon.isode.net:6222/adlon.isode.net"));

			spn.setInstancePort(0);
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/mlink.adlon.isode.net/adlon.isode.net"));

			WindowsServicePrincipalName spn2("mlink.adlon.isode.net");

			spn2.setInstancePort(6222);
			CPPUNIT_ASSERT_EQUAL(spn2.toString(), std::string("xmpp/mlink.adlon.isode.net:6222"));

			spn2.setInstancePort(0);
			CPPUNIT_ASSERT_EQUAL(spn2.toString(), std::string("xmpp/mlink.adlon.isode.net"));
		}

		void testReferrer() {
			WindowsServicePrincipalName spn("127.0.0.1");

			spn.setReferrer("referrer.net");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/127.0.0.1/referrer.net"));

			spn.setInstancePort(6222);
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/127.0.0.1:6222/referrer.net"));

			spn.setReferrer("हिन्दी.net");
			CPPUNIT_ASSERT_EQUAL(spn.toString(), std::string("xmpp/127.0.0.1:6222/हिन्दी.net"));

			try {
				spn.setReferrer("referrer/net"); /* Foward slash not allowed */
				spn.toString();
				CPPUNIT_ASSERT(false);
			} catch (std::runtime_error) {
				/* expected */
			}

			try {
				spn.setReferrer(""); /* seems like you must have referrer with an IP */
				spn.toString();
				CPPUNIT_ASSERT(false);
			} catch (std::runtime_error) {
				/* expected */
			}

			WindowsServicePrincipalName spn2("mlink.adlon.isode.net");

			spn2.setReferrer("referrer.net"); /* Referrer ignored if service name is not IP */
			CPPUNIT_ASSERT_EQUAL(spn2.toString(), std::string("xmpp/mlink.adlon.isode.net"));

			spn2.setReferrer("referrer/net"); /* Referrer ignored if service name is not IP */
			CPPUNIT_ASSERT_EQUAL(spn2.toString(), std::string("xmpp/mlink.adlon.isode.net"));

			WindowsServicePrincipalName spn3("adlon.isode.net");

			spn3.setInstanceName("mlink.adlon.isode.net");
			spn3.setInstancePort(6222);
			spn3.setReferrer("referrer.net"); /* Referrer ignored if service name is not IP */
			CPPUNIT_ASSERT_EQUAL(spn3.toString(), std::string("xmpp/mlink.adlon.isode.net:6222/adlon.isode.net"));

		}
};

CPPUNIT_TEST_SUITE_REGISTRATION(WindowsServicePrincipalNameTest);
